package com.wang.interview.threads;

import java.util.concurrent.*;

/**
 * @author: wang
 * @date: 2021/7/25 11:17
 * @description:线程池
 *优点：减少多次创建线程的开销，方便控制管理线程，如控制最大线程数量
 * 共有：3种直接使用的线程池，都是ThreadPoolExecutor的一种构造出的实例
 * 1、SingleThreadExecutor   // 一池一个线程
 * 2、FixedThreadPool        // 在创建的时候固定线程数量
 * 3、CachedThreadPool       // keepAliveTime 60L seconds ，maximumPoolSize Integer.Max_Value
 * 以上三种并不推荐使用，因为2线程数量固定容易导致请求堆积产生OOM，3则是可能创建过多线程导致OOM
 * 所以使用ThreadPoolExecutor 最全的构造方法:7个参数来自定义线程池
 * 七大参数：
 *  1、int corePoolSize                      // 默认线程数
 *  2、int maximumPoolSize                   // 扩容后的最大线程数
 *  3、long keepALiveTime                    // 线程闲置且数量超过默认时，线程的保留时间
 *  4、TimeUnit unit                         // 结合 3
 *  5、BlockingQueen<Runnable> workQueen     // 阻塞队列，存放待执行的请求
 *      -- 常用的阻塞队列又分为三种：
 *      1、SynchronousQueue(capacity)      // 超过core直接创建新线程
 *      2、LinkedBlockingQueen(capacity)   // 超过core+c创建，可以无界：即c可以没有
 *      3、ArrayBlockingQueue(capacity)    // 有界
 *      4、DelayQueue                      // 暂时用不来
 *  6、ThreadFactory threadFactory           // 创建线程的工厂
 *  7、rejectedExecutionHandler handler      // 请求数量超过max和queen的数量时，执行的拒绝策略
 *    其中拒绝策略又分为四种：
 *    ThreadPoolExecutor.AbortPolicy           // 默认拒绝策略，报异常：java.util.concurrent.RejectedExecutionException
 *    ThreadPoolExecutor.CallerRunsPolicy      // 将多余请求回退会发起请求的线程
 *    ThreadPoolExecutor.DiscardOldestPolicy   // 抛弃无法处理的请求，不会有任何表现
 *    ThreadPoolExecutor.DiscardPolicy         // 抛弃等待时间最长的线程，不会有任何表现
 *
 * 扩容过程：
 *
 *
 */
public class ThreadPoolTest {

    public static void main(String[] args) {
        /*ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();*/
        /*ThreadPoolExecutor.AbortPolicy;
        ThreadPoolExecutor.CallerRunsPolicy;
        ThreadPoolExecutor.DiscardOldestPolicy;
        ThreadPoolExecutor.DiscardPolicy;*/

        // 创建自定义线程池
        ExecutorService pool = new ThreadPoolExecutor(1,5,3
                ,TimeUnit.SECONDS,new LinkedBlockingQueue<>(5),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());
//        ExecutorService pool = Executors.newCachedThreadPool();
        for (int i = 0; i < 100; i++) {
            pool.execute(()->{
                System.out.println(Thread.currentThread().getName()+":过来办理业务！");
            });
        }

        pool.shutdown();
    }
}

